package net.sourceforge.gjtapi.protocols.playback; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.net.UnknownServiceException; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import net.sourceforge.gjtapi.protocols.JavaSoundParser; /** * A {@link URLConnection} for the playback protocol. * @author Renato Cassaca * @author Dirk Schnelle-Walka * @version 1.0 */ public class PlaybackURLConnection extends URLConnection { /** Microfone access point. */ private SourceDataLine line; /** Write point given to clients. */ private OutputStream outputStream; /** The audio format to use. */ private AudioFormat audioFormat; /** * Constructs a new object. * * @param url * URL */ public PlaybackURLConnection(final URL url) { super(url); // Validate the kind of input supported if (!url.getAuthority().equals("audio")) { throw new UnsupportedOperationException( "Can only process 'audio'. " + url.getAuthority() + " is unsupported"); } } /** * {@inheritDoc} * * Closes any open line. */ protected void finalize() throws Throwable { if (outputStream != null) { try { outputStream.close(); } catch (IOException ignore) { } outputStream = null; } if (line != null) { if (line.isOpen()) { line.close(); } line = null; } } /** * {@inheritDoc} */ public void connect() throws IOException { if (connected) { return; } // Get audio format that will open playback AudioFormat format = getAudioFormat(); // Representation of the line that will be opened DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); // Checks if line is supported if (!AudioSystem.isLineSupported(info)) { throw new IOException("Cannot open the requested line: " + info.toString()); } // Obtain, open and start the line. try { line = (SourceDataLine) AudioSystem.getLine(info); line.open(format, AudioSystem.NOT_SPECIFIED); // Starts the line line.start(); } catch (LineUnavailableException ex) { throw new IOException("Line is unavailable"); } // Marks this URLConnection as connected connected = true; } /** * Given URI parameters, constructs an AudioFormat. * * @return AudioFormat * @exception IOException * error determining the audio format. */ public AudioFormat getAudioFormat() throws IOException { if (audioFormat == null) { final URL url = getURL(); try { audioFormat = JavaSoundParser.parse(url); } catch (URISyntaxException e) { throw new IOException(e.getMessage()); } } return audioFormat; } /** * {@inheritDoc} * Throws an {@link UnknownServiceException}. * * @throws IOException * input streams are not supported by the capture protocol. */ public InputStream getInputStream() throws IOException { throw new UnknownServiceException("Cannot read from a playback device"); } /** * {@inheritDoc} */ public OutputStream getOutputStream() throws IOException { if (outputStream == null) { outputStream = new LineOutputStream(line); } return outputStream; } }